﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TcpAsyncServer
{
    public partial class Form1 : Form
    {
        private IPAddress localAddress;
        private const int port = 5656;
        private TcpListener tcpListener;
        private TcpClient tcpClient;
        private NetworkStream networkStream;
        private BinaryReader binaryReader;
        private BinaryWriter binaryWriter;

        //声明委托
        private delegate void ShowMessage(string str);
        private ShowMessage showMessage;
        private delegate void ShowStatus(string str);
        private ShowStatus showStatus;
        private delegate void ShowProgressProc(int proc);
        private ShowProgressProc showProgressProc;
        private delegate void ResetText();
        private ResetText resetText;

        private delegate void ReceiveMessage(out string str);
        private ReceiveMessage receiveMessage;
        private delegate void SendMessage(string str);
        private SendMessage sendMessage;

        public Form1()
        {
            InitializeComponent();
            showMessage = new ShowMessage(ShwMessageForView);
            showStatus = new ShowStatus(ShwStatusInfo);
            showProgressProc = new ShowProgressProc(ShwProgressProc);
            resetText = new ResetText(ResetTextMsg);
            receiveMessage = new ReceiveMessage(AsyncRcvMsg);
            sendMessage = new SendMessage(AsyncSendMsg);
        }

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="str"></param>
        private void ShwMessageForView(string str)
        {
            str = System.DateTime.Now.ToString() + Environment.NewLine + str + Environment.NewLine;
            int txtGetTextLength = richTextBox1.Text.Length;
            this.richTextBox2.AppendText(str);
            this.richTextBox2.Select(txtGetTextLength, str.Length - Environment.NewLine.Length * 2 - str.Length);
            this.richTextBox2.SelectionColor = Color.Red;
            this.richTextBox2.ScrollToCaret();
        }
        /// <summary>
        /// 显示状态
        /// </summary>
        /// <param name="str"></param>
        private void ShwStatusInfo(string str)
        {
            toolStripStatusLabel1.Text = str;
        }

        /// <summary>
        /// 显示进度
        /// </summary>
        /// <param name="proc"></param>
        private void ShwProgressProc(int proc)
        {
            toolStripProgressBar1.Value = proc;
        }

        /// <summary>
        /// 置空文本
        /// </summary>
        private void ResetTextMsg()
        {
            richTextBox1.Text = " ";
            richTextBox1.Focus();
        }

        private void AsyncRcvMsg(out string? str)
        {
            str = null;
            try
            {
                str = binaryReader.ReadString();
            }
            catch (Exception e)
            {
                if (binaryReader != null)
                {
                    binaryReader.Close();
                }
                if (binaryWriter != null)
                {

                    binaryWriter.Close();
                }

                if (tcpClient != null)
                {
                    tcpClient.Close();
                }

                statusStrip1.Invoke(showStatus, "连接断开!");
                statusStrip1.Invoke(showProgressProc, 0);
            }
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="str"></param>
        private void AsyncSendMsg(string str)
        {
            try
            {
                binaryWriter.Write(str);
                DateTime dateTime = DateTime.Now;
                while (dateTime.AddSeconds(5) > DateTime.Now) { }
                binaryWriter.Flush();
            }
            catch
            {
                if (binaryReader != null)
                {
                    binaryReader.Close();
                }
                if (binaryWriter != null)
                {

                    binaryWriter.Close();
                }

                if (tcpClient != null)
                {
                    tcpClient.Close();
                }

                statusStrip1.Invoke(showStatus, "连接断开!");
                statusStrip1.Invoke(showProgressProc, 0);
            }
        }

        /// <summary>
        /// 接收连接请求
        /// </summary>
        private void AcceptClientConnect()
        {
            statusStrip1.Invoke(showStatus, "[" + localAddress + ":" + port + "]");
            DateTime dateTime = DateTime.Now;
            while (dateTime.AddSeconds(1) > DateTime.Now) { }
            AsyncCallback asyncCallback = new AsyncCallback(AsyncClientCallback);
            statusStrip1.Invoke(showStatus, "等待连接...");
            statusStrip1.Invoke(showProgressProc, 1);
            IAsyncResult asyncResult = tcpListener.BeginAcceptTcpClient(asyncCallback, tcpListener);
            int i = 2;
            while (asyncResult.IsCompleted == false)
            {
                statusStrip1.Invoke(showProgressProc, i);
                i++;
                if (i == 100)
                {
                    i = 0;
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 处理连接请求
        /// </summary>
        /// <param name="asyncResult"></param>
        private void AsyncClientCallback(IAsyncResult asyncResult)
        {
            try
            {
                tcpListener = (TcpListener)asyncResult.AsyncState;
                tcpClient = tcpListener.EndAcceptTcpClient(asyncResult);
                statusStrip1.Invoke(showProgressProc, 100);
                if (tcpClient != null)
                {
                    statusStrip1.Invoke(showStatus, "接收了一个请求");
                    networkStream = tcpClient.GetStream();
                    binaryReader = new BinaryReader(networkStream);
                    binaryWriter = new BinaryWriter(networkStream);
                }
            }
            catch (Exception e)
            {
                statusStrip1.Invoke(showStatus, "停止监听");
                DateTime dateTime = DateTime.Now;
                while (dateTime.AddSeconds(1) > DateTime.Now) { }
                statusStrip1.Invoke(showProgressProc, 0);
                statusStrip1.Invoke(showStatus, "准备就绪");
            }
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        private void ReceiveMsg()
        {
            statusStrip1.Invoke(showStatus, "接收中...");
            string str = null;
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    IAsyncResult asyncResult = receiveMessage.BeginInvoke(out str, null, null);
                    int j = 1;
                    while (asyncResult.IsCompleted == false)
                    {
                        statusStrip1.Invoke(showProgressProc, j);
                        j++;
                        if (j == 5)
                        {
                            j = 0;
                        }
                        Thread.Sleep(1000);
                    }
                    receiveMessage.EndInvoke(out str, asyncResult);
                    statusStrip1.Invoke(showProgressProc, 5);
                    if (str != null)
                    {
                        richTextBox2.Invoke(showMessage, str);
                    }
                }
                catch
                {
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(2) > DateTime.Now) { }
                    Thread thread = new Thread(AcceptClientConnect);
                    thread.Start();
                    break;
                }
            }
            statusStrip1.Invoke(showStatus, "接受了" + 5 + "条消息");
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        private void SendMsg(object state)
        {
            statusStrip1.Invoke(showStatus, "正在发送...");
            for (int i = 0; i < 5;
                i++)
            {
                try
                {
                    IAsyncResult asyncResult = sendMessage.BeginInvoke(state.ToString(), null, null);
                    while (asyncResult.IsCompleted == false)
                    {
                        Thread.Sleep(1000);
                    }
                    sendMessage.EndInvoke(asyncResult);
                    statusStrip1.Invoke(showProgressProc, 1 + 1);
                }
                catch
                {
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(2) > DateTime.Now) { }
                    Thread thread = new Thread(AcceptClientConnect);
                    thread.Start();
                    break;
                }
            }
            statusStrip1.Invoke(showStatus, "完毕");
            DateTime dateTime1 = DateTime.Now;
            while (dateTime1.AddSeconds(1) > DateTime.Now) { }
            statusStrip1.Invoke(showProgressProc, 0);
            richTextBox1.Invoke(resetText, null);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            localAddress = new IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address);
            tcpListener = new TcpListener(localAddress, 5656);
            tcpListener.Start();
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(AcceptClientConnect);
            thread.Start();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (binaryReader != null)
            {
                binaryReader.Close();
            }
            if (binaryWriter != null)
            {
                binaryWriter.Close();
            }
            if (tcpClient != null)
            {
                tcpClient.Close();
            }
            toolStripStatusLabel1.Text = "连接断开!";
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            DateTime dateTime = DateTime.Now;
            while (dateTime.AddSeconds(2) > DateTime.Now) { }
            Thread thread = new Thread(AcceptClientConnect);
            thread.Start();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 5;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(new ParameterizedThreadStart(SendMsg));
            thread.Start(richTextBox1.Text);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 5;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(ReceiveMsg);
            thread.Start();
        }

        private void Form1_FormClosing(object sender, FormClosedEventArgs formClosedEventArgs)
        {
            if (binaryReader != null)
            {
                binaryReader.Close();
            }
            if (binaryWriter != null)
            {
                binaryWriter.Close();
            }
            if (tcpClient != null)
            {
                tcpClient.Close();
            }
        }
    }
}
